import { last, remove } from "lodash";
import Taro from "@tarojs/taro";
import { generateUuid } from "@/utils/common";
import { IQItem } from "@/pages/index/hooks/type";
// import { TextDecoder } from "text-encoding";
// import { decode } from "fastestsmallesttextencoderdecoder";

export const DEFAULT_RECOMMENDED_NUMBER = 6;
const DEFAULT_TITLE = "有什么可以帮助你的？";

/**
 * @CHAT_ROLE 会话角色
 */
export enum CHAT_ROLE {
  /**
   * @user 提问者
   */
  user = "user",
  /**
   * @assistant ai
   */
  assistant = "assistant",
  /**
   * @view 回答间隙预览
   */
  view = "view",
  error = "error",
}

/**
 * @DEVICE_TYPE 设备类型
 */
export enum DEVICE_TYPE {
  /**
   * @web 网页
   */
  web = "web",
  /**
   * @pc pc客户端
   */
  pc = "pc",
  /**
   * @app 手机APP
   */
  app = "app",
  /**
   * @wechatMiniProgram 微信小程序
   */
  wechatMiniProgram = "wechatMiniProgram",
}

export type deviceType = {
  readonly [K in keyof typeof DEVICE_TYPE]: K;
};
/**
 * @SESSION_TYPE 会话类型
 */
export enum SESSION_TYPE {
  /**
   * @text_chat 文本会话
   */
  text_chat = "text_chat",
  /**
   * @image_chat 图片会话
   */
  image_chat = "image_chat",
  /**
   * @file_chat 文件会话
   */
  file_chat = "file_chat",
}

/**
 * @CHAT_EVENT chunk event
 */
export enum CHAT_EVENT {
  ERROR = "ERROR",
  MESSAGE = "MESSAGE",
  DONE = "DONE",
  PING = "PING",
}

/**
 * @CHAT_ACTION 会话行为
 */
export enum CHAT_ACTION {
  /**
   * @next 下一个
   */
  next = "next",
  /**
   * @variant 重新生成
   */
  variant = "variant",
}

export const DEFAULT_RECOMMEND_LIST = [
  "H-K方法在计算微孔分布时基于什么假设？",
  "TPFSD方法除了定量吸附数据，还有哪些优点？",
  "如何测定催化剂活性中心性质？",
  "金属氧化物与金属相比，为什么在催化反应中应用更广泛？",
  "SiO₂上吸附的吡啶的拉曼光谱有哪些特点？请详细描述。",
  "催化剂活性中心的性质包括哪些方面？",
];
// 初始化展示的列表内容
export const DEFAULT_Q_LIST = [
  {
    id: generateUuid(),
    role: CHAT_ROLE.assistant,
    childMsgId: [],
    interrupted: false,
    messageBody: {
      chartData: {},
      contents: [
        {
          // "content": `<p>Hi，你好，我是你的工业工厂助手</p><p>你可以问我：</p><p>• 帮我生成最近三年的运营报表</p><p>• 给出过去一小时溶剂至反应器流量平稳率趋势</p><p>• 16:00的氢气流量的值是多少？</p><p>• 上午九点搅拌机电流与反应器液位趋势</p>`,
          content: DEFAULT_TITLE,
          role: CHAT_ROLE.assistant,
        },
      ],
      recommended: {
        chatId: "",
        clientId: "Recommendation",
        content: DEFAULT_RECOMMEND_LIST,
      },
    },
    msgId: "",
    parentMsgId: "",
    sessionId: "",
  },
];

export const DEFAULT_ERROR_ITEM = {
  id: generateUuid(),
  role: CHAT_ROLE.view,
  messageBody: {
    chartData: {},
    contents: [
      {
        content: ``,
        contentType: "text",
        role: CHAT_ROLE.assistant,
      },
    ],
  },
};

/**
 * @description: 获取默认的对话列表
 * @param {Array} recommendedList 推荐列表
 * @return {*}
 */
export const getDefaultQuestionList = (recommendedList: Array<string>) => {
  return [
    {
      id: generateUuid(),
      role: CHAT_ROLE.assistant,
      childMsgId: [],
      interrupted: false,
      messageBody: {
        chartData: {},
        contents: [
          {
            content: DEFAULT_TITLE,
            role: CHAT_ROLE.assistant,
          },
        ],
        recommended: {
          chatId: "",
          clientId: "Recommendation",
          content: recommendedList || DEFAULT_RECOMMEND_LIST,
        },
      },
      msgId: "",
      parentMsgId: "",
      sessionId: "",
    },
  ];
};

/**
 * @description: 获取对话项的文本内容
 * @param {IQItem} item
 * @return {*} content
 */
export const getChatItemContent = (item: IQItem) => {
  const chatContent = item?.messageBody?.contents?.[0]?.content ?? "";
  return chatContent;
};

/**
 * @description: 根据 会话接口 切片 处理返回的内容
 * @param {*} response chunk arrayBuffer
 * @return {*} 切片解析出来最后的 一个对象会话内容
 */
export const handleChunkResp = (response) => {
  let arrayBuffer = response.data; // 接收持续返回的数据
  let uint8Array = new Uint8Array(arrayBuffer);
  let text = Taro.arrayBufferToBase64(uint8Array);
  const base64ToUtf8 = (base64String) => {
    // base64转utf8 这个方法可以提出去 我这里方便展示
    // new TextDecoder() 小程序真机中没有这个方法，得下载一个这个 text-encoding
    // npm install text-encoding --save-dev
    // 引入import { TextDecoder } from "text-encoding/lib/encoding";
    const bytes = Taro.base64ToArrayBuffer(base64String);
    const utf8String = new TextDecoder().decode(bytes);
    // const utf8String = decode(bytes);
    return utf8String;
  };
  text = base64ToUtf8(text);
  console.log("onChunkReceived base64ToUtf8 text", text);
  // let eventRegex = /event:\[(.*?)\]\s*data:(\{.*?\})/g;
  // let eventRegex = /event:\[(.*?)\]\s*data:(\{.*?\})(?=\sevent:\[|\s*$)/g;
  let eventRegex = /event:\[(.*?)\]\s*data:(.*?)(?=\sevent:\[|\s*$)/g;

  // 匹配所有符合条件的字符串
  let matches = [...text.matchAll(eventRegex)];
  console.log("matches", matches);
  if (!matches.length) {
    // 类似直接接口报错 直接返回了
    // {"isSuccess":false,"success":false,"code":"500","requestId":"APP_aaac0518b0","msg":"抱歉，我不知道如何回复您的问题_。"}
    const { success, code, msg } = JSON.parse(text);
    // TODO: 这边需要 登录啥的
    if (!success) {
      let resData = {
        event: CHAT_EVENT.ERROR,
        data: msg,
      };
      return [resData.event, resData];
    }
  }
  // 转换匹配结果为所需的数组格式
  let result = matches.map((match) => {
    console.log("match", match);
    // 解析JSON字符串为对象
    let eventData = {};
    try {
      eventData = JSON.parse(match[2]);
      return {
        event: match[1],
        data: eventData,
      };
    } catch (e) {
      console.error("Parsing eventData error:", e);
    }
    return {
      event: match[1],
      data: match[2],
    };
  });

  const cData: any = last(result) ?? {};
  const resData = cData?.data ?? {};
  return [cData.event, resData];
};

export interface IChatHistoryItem {
  id: string;
  content?: string;
}

export const addChatHistory = (chat: IChatHistoryItem) => {
  let oldChatHistory = Taro.getStorageSync("chatHistory") || [];
  oldChatHistory.unshift(chat);
  Taro.setStorageSync("chatHistory", oldChatHistory);
};
export const setChatHistory = (chatList: Array<IChatHistoryItem>) => {
  Taro.setStorageSync("chatHistory", chatList);
};

export const destoryChatHistory = (id: string) => {
  let oldChatHistory = Taro.getStorageSync("chatHistory") || [];
  let newChatHistory = remove(
    oldChatHistory,
    function (chat: IChatHistoryItem) {
      return chat.id == id;
    }
  );
  Taro.setStorageSync("chatHistory", newChatHistory);
};

export const selectChatHistoryItem = (item: IChatHistoryItem) => {
  Taro.setStorageSync("chatContext", item);
};
export const updateHistoryById = (id: string, newItem: IChatHistoryItem) => {
  let cHistoryList = Taro.getStorageSync("chatHistory") || [];
  let newHistoryList = cHistoryList.map((item: IChatHistoryItem) => {
    if (item.id == id) {
      return (item = { ...item, ...newItem });
    } else {
      return item;
    }
  });
  Taro.setStorageSync("chatHistory", newHistoryList);
};

export const clearChatContext = () => {
  Taro.setStorageSync("chatContext", {});
};

export const clearChatHistory = () => {
  Taro.setStorageSync("chatHistory", []);
};

export const clearAllChat = () => {
  clearChatContext();
  clearChatHistory();
};
